__version__ = '1.0.0d1'
__api_version__ = '1.2.1'
#__all__ = 'Smuggler'

import urllib
import httplib2
import errors
import re
from method import MethodRunner, Response
            
class Smuggler(object):
    apiUri = 'api.smugmug.com/services/api/json/1.2.1/'
    apiUploadUri = 'uploads.smugmug.com/'
    userAgent = 'Python Smuggler API/%s' % __version__
    useSsl = False

    def __init__(self):
        self.session = None
        self.methods = {}
        
        # Re-use the Http object
        self.http = httplib2.Http()
        
    def execute(self, method, *args, **kwargs):
        request = method(self, *args, **kwargs)
         
        uri = request.uri or self.apiUri
        if request.useSsl or self.useSsl:
            uri = 'https://%s' % uri
        else:
            uri = 'http://%s' % uri
                    
        headers = {
            'Accept' : 'application/json',
            'Content-Length' : '0',
            'User-Agent' : self.userAgent,
            'X-Smug-Version' : __api_version__,
            'X-Smug-ResponseType' : 'JSON'
        }            
        
        params = {}
        
        if method.name:
            params['method'] = method.name
        
        if self.session:
            params['SessionID'] = self.session.id
            headers['X-Smug-SessionID'] = self.session.id
        
        if request.params:
            params.update(request.params)
            
        if request.headers:
            headers.update(request.headers)
                
        paramStr = '' 
        body = None
        httpMethod = request.httpMethod
        if request.body:
            # This is some sort of PUT/POST request, we have to send the params as headers
            for k, v in params:
                headers['X-Smug-%s' % k] = re.sub(r'\r\n|\n', r'\r', v).encode('utf-8')
                
            body = request.body
        elif request.data:
            if request.data:
                params.update(request.data)
                
            httpMethod = 'POST'
            body = urllib.urlencode([(k, v) for (k, v) in params.iteritems() if v]).encode('utf-8')
        else:
            # Do a GET  
            paramStr = '?' + urllib.urlencode([(k, v) for (k, v) in params.iteritems() if v]).encode('utf-8')
            
        del request
        
        resp, content = self.http.request(uri + paramStr, httpMethod, body=body, headers=headers)

        response = Response(resp, content)

        if response.headers['status'] != '200':
            raise Exception('Got unexpected HTTP status %s' % response.headers['status'])
        elif response.stat == 'fail':
            raise errors.get(response.code, response.message)
        elif response.stat != 'ok':
            print response.content
            raise Exception('Stat is not OK')
        elif response.method != method.name:
            raise Exception('Method "%s" did not match requested method "%s"' % (response.method, method.name))

        response = method.on_success(self, response)
        
        if method.responseKey:
            return response.content[method.responseKey]           

        
        return response.content
        
    def __getattr__(self, key):       
        module = __import__(key, globals(), locals())
             
        return MethodRunner(key, self, module)
        